<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="Wretch - A tiny wrapper built around fetch with an intuitive, chainable syntax">
  <title>Wretch - The Tiny Fetch Wrapper</title>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link
    href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&family=JetBrains+Mono:wght@400&display=swap"
    rel="stylesheet">
  <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet">
  <link href="./index.css" rel="stylesheet">
  <style>
    /* Prism theme overrides to match design */
    code[class*="language-"],
    pre[class*="language-"] {
      background: transparent !important;
      text-shadow: none !important;
    }

    .token.comment {
      color: #7a7a8c;
    }

    .token.string {
      color: #b9ca4a;
    }

    .token.keyword {
      color: #c397d8;
    }

    .token.function {
      color: #7aa6da;
    }

    .token.number {
      color: #e78c45;
    }

    .token.operator {
      color: #e7c547;
    }
  </style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-javascript.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-bash.min.js"></script>
</head>

<body>
  <div class="background-gradient"></div>
  <div class="background-orbs">
    <div class="orb orb-1"></div>
    <div class="orb orb-2"></div>
    <div class="orb orb-3"></div>
  </div>

  <section class="front-section" id="front">
    <div class="logo">
      <img src="./assets/wretch.svg" alt="wretch-logo">
    </div>
    <h1>Wretch</h1>
    <p class="shortdesc">A tiny <span class="highlight">(~1.8KB gzipped)</span> wrapper built around fetch with an
      intuitive syntax.</p>

    <div class="tags-wrapper">
      <div class="tags">
        <button class="tag" data-feature="Immutable">
          <i data-lucide="shield-check"></i>
          Immutable
        </button>
        <button class="tag" data-feature="Intuitive">
          <i data-lucide="lightbulb"></i>
          Intuitive
        </button>
        <button class="tag" data-feature="Chainable">
          <i data-lucide="link"></i>
          Chainable
        </button>
        <button class="tag" data-feature="Isomorphic">
          <i data-lucide="globe"></i>
          Isomorphic
        </button>
        <button class="tag" data-feature="Modular">
          <i data-lucide="puzzle"></i>
          Modular
        </button>
      </div>
      <div class="tags-boxes">
        <div class="tag-box Immutable">
          <p>Wretch does not mutate its internal state. Each function returns a copy of the original object.</p>
        </div>
        <div class="tag-box Intuitive">
          <p>Wretch's syntax is readable and concise. Includes TypeScript definition files for autocompletion.</p>
        </div>
        <div class="tag-box Chainable">
          <p>All methods are 100% chainable. Because <code>a.b().c()</code> is prettier than
            <code>var z = a; z.b(); z.c()</code>.
          </p>
        </div>
        <div class="tag-box Isomorphic">
          <p>Wretch is compatible with browsers and Node.js. Use any polyfill you like!</p>
        </div>
        <div class="tag-box Modular">
          <p>Use Addons to add new methods and capabilities. Use Middlewares to intercept requests and fully customize
            Wretch behaviour.</p>
        </div>
      </div>
    </div>

    <div class="front-links">
      <a class="btn btn-primary" href="https://github.com/elbywan/wretch" target="_blank" rel="noopener noreferrer">
        <i data-lucide="github"></i>
        <span>View on GitHub</span>
      </a>
      <a class="btn btn-secondary" href="https://www.npmjs.com/package/wretch" target="_blank"
        rel="noopener noreferrer">
        <i data-lucide="package"></i>
        <span>Package</span>
      </a>
      <a class="btn btn-secondary" href="https://elbywan.github.io/wretch/api" target="_blank"
        rel="noopener noreferrer">
        <img src="assets/ts-logo.svg" alt="TypeScript">
        <span>API Documentation</span>
      </a>
    </div>

    <div class="install-tabs">
      <button class="install-tab active" data-tab="npm">npm</button>
      <button class="install-tab" data-tab="yarn">yarn</button>
      <button class="install-tab" data-tab="pnpm">pnpm</button>
      <button class="install-tab" data-tab="bun">bun</button>
      <button class="install-tab" data-tab="cdn">CDN</button>
    </div>
    <div class="install-content">
      <div class="install-panel active" data-panel="npm">
        <pre><code class="language-bash">npm i wretch</code></pre>
        <button class="copy-btn" aria-label="Copy to clipboard"><i data-lucide="copy"></i></button>
      </div>
      <div class="install-panel" data-panel="yarn">
        <pre><code class="language-bash">yarn add wretch</code></pre>
        <button class="copy-btn" aria-label="Copy to clipboard"><i data-lucide="copy"></i></button>
      </div>
      <div class="install-panel" data-panel="pnpm">
        <pre><code class="language-bash">pnpm add wretch</code></pre>
        <button class="copy-btn" aria-label="Copy to clipboard"><i data-lucide="copy"></i></button>
      </div>
      <div class="install-panel" data-panel="bun">
        <pre><code class="language-bash">bun add wretch</code></pre>
        <button class="copy-btn" aria-label="Copy to clipboard"><i data-lucide="copy"></i></button>
      </div>
      <div class="install-panel" data-panel="cdn">
        <pre><code class="language-markup">&lt;script src="https://unpkg.com/wretch"&gt;&lt;/script&gt;</code></pre>
        <button class="copy-btn" aria-label="Copy to clipboard"><i data-lucide="copy"></i></button>
      </div>
    </div>
  </section>

  <button id="scroll-to-top" aria-label="Scroll to top">
    <i data-lucide="arrow-up"></i>
  </button>

  <section class="usage" id="usage">
    <h1>Quick Start</h1>
    <p class="usage-subtitle">Build beautiful, chainable HTTP requests in seconds</p>

    <div class="usage-steps">
      <div class="step-card">
        <div class="step-number">1</div>
        <div class="step-content code-copy-reference">
          <div class="step-header">
            <i data-lucide="package"></i>
            <h3>Import wretch</h3>
            <div class="step-actions">
              <a href="https://github.com/elbywan/wretch#usage" class="step-link" target="_blank"
                rel="noopener noreferrer">
                <i data-lucide="external-link"></i>
              </a>
              <button class="copy-btn" aria-label="Copy code"><i data-lucide="copy"></i></button>
            </div>
          </div>
          <pre><code class="language-javascript">import wretch from "wretch"</code></pre>
        </div>
      </div>

      <div class="step-card">
        <div class="step-number">2</div>
        <div class="step-content code-copy-reference">
          <div class="step-header">
            <i data-lucide="zap"></i>
            <h3>Create an instance</h3>
            <div class="step-actions">
              <button class="copy-btn" aria-label="Copy code"><i data-lucide="copy"></i></button>
            </div>
          </div>
          <pre><code class="language-javascript">wretch()</code></pre>
        </div>
      </div>

      <div class="step-card">
        <div class="step-number">3</div>
        <div class="step-content code-copy-reference">
          <div class="step-header">
            <i data-lucide="settings"></i>
            <h3>Configure with helpers</h3>
            <div class="step-actions">
              <a href="https://github.com/elbywan/wretch#helper-methods-" class="step-link" target="_blank"
                rel="noopener noreferrer">
                <i data-lucide="external-link"></i>
              </a>
              <button class="copy-btn" aria-label="Copy code"><i data-lucide="copy"></i></button>
            </div>
          </div>
          <pre><code class="language-javascript">  .url("https://jsonplaceholder.typicode.com/users")</code></pre>
        </div>
      </div>

      <div class="step-card">
        <div class="step-number">4</div>
        <div class="step-content code-copy-reference">
          <div class="step-header">
            <i data-lucide="upload"></i>
            <h3>Add request body</h3>
            <div class="step-actions">
              <a href="https://github.com/elbywan/wretch#body-types-" class="step-link" target="_blank"
                rel="noopener noreferrer">
                <i data-lucide="external-link"></i>
              </a>
              <button class="copy-btn" aria-label="Copy code"><i data-lucide="copy"></i></button>
            </div>
          </div>
          <pre><code class="language-javascript">  .json({ name: "John Doe", email: "john@example.com" }) // .formData, .formUrl…</code></pre>
        </div>
      </div>

      <div class="step-card">
        <div class="step-number">5</div>
        <div class="step-content code-copy-reference">
          <div class="step-header">
            <i data-lucide="send"></i>
            <h3>Execute HTTP method</h3>
            <div class="step-actions">
              <a href="https://github.com/elbywan/wretch#http-methods-" class="step-link" target="_blank"
                rel="noopener noreferrer">
                <i data-lucide="external-link"></i>
              </a>
              <button class="copy-btn" aria-label="Copy code"><i data-lucide="copy"></i></button>
            </div>
          </div>
          <pre><code class="language-javascript">  .post() // .get, .put, .patch, .delete…</code></pre>
        </div>
      </div>

      <div class="step-card">
        <div class="step-number">6</div>
        <div class="step-content code-copy-reference">
          <div class="step-header">
            <i data-lucide="alert-circle"></i>
            <h3>Handle errors</h3>
            <div class="step-actions">
              <a href="https://github.com/elbywan/wretch#catchers-" class="step-link" target="_blank"
                rel="noopener noreferrer">
                <i data-lucide="external-link"></i>
              </a>
              <button class="copy-btn" aria-label="Copy code"><i data-lucide="copy"></i></button>
            </div>
          </div>
          <pre><code class="language-javascript">  .notFound(err => console.log("User not found")) // .unauthorized, .forbidden…
  .error(500, err => console.log("Server error"))</code></pre>
        </div>
      </div>

      <div class="step-card">
        <div class="step-number">7</div>
        <div class="step-content code-copy-reference">
          <div class="step-header">
            <i data-lucide="download"></i>
            <h3>Parse response</h3>
            <div class="step-actions">
              <a href="https://github.com/elbywan/wretch#response-types-" class="step-link" target="_blank"
                rel="noopener noreferrer">
                <i data-lucide="external-link"></i>
              </a>
              <button class="copy-btn" aria-label="Copy code"><i data-lucide="copy"></i></button>
            </div>
          </div>
          <pre><code class="language-javascript">  .json() // .text, .blob, .arrayBuffer…</code></pre>
        </div>
      </div>
    </div>

    <div class="complete-example-section">
      <h2>Complete Example</h2>
      <p class="usage-subtitle">See all the pieces come together in one beautiful chain</p>

      <div class="complete-example">
        <pre><code class="language-javascript">import wretch from "wretch"

const user = await wretch("https://jsonplaceholder.typicode.com/users")
  .json({ name: "John Doe", email: "john@example.com" })
  .post()
  .notFound(err => console.log("User not found"))
  .error(500, err => console.log("Server error"))
  .json()

console.log(user)</code></pre>
        <button class="copy-btn" aria-label="Copy code"><i data-lucide="copy"></i></button>

        <div class="example-features">
          <a href="https://github.com/elbywan/wretch#addons" class="feature-link" target="_blank"
            rel="noopener noreferrer">
            <i data-lucide="sparkles"></i>
            <div>
              <strong>Explore Addons</strong>
              <span>Extend functionality with query strings, form data, and more</span>
            </div>
          </a>
          <a href="https://github.com/elbywan/wretch#middlewares" class="feature-link" target="_blank"
            rel="noopener noreferrer">
            <i data-lucide="layers"></i>
            <div>
              <strong>Use Middlewares</strong>
              <span>Add retry logic, caching, throttling, and custom interceptors</span>
            </div>
          </a>
        </div>
      </div>
    </div>
  </section>

  <footer>
    <div class="footer-content">
      <div class="footer-left">
        <img src="./assets/wretch.svg" alt="Wretch logo" class="footer-logo">
        <p>Built with <span class="heart">♥</span> by <a href="https://github.com/elbywan" target="_blank"
            rel="noopener noreferrer">Julien Elbaz</a></p>
      </div>
      <div class="footer-right">
        <div class="footer-links">
          <a href="https://github.com/elbywan/wretch" target="_blank" rel="noopener noreferrer">
            <i data-lucide="github"></i> GitHub
          </a>
          <a href="https://www.npmjs.com/package/wretch" target="_blank" rel="noopener noreferrer">
            <i data-lucide="package"></i> npm
          </a>
          <a href="https://elbywan.github.io/wretch/api" target="_blank" rel="noopener noreferrer">
            <i data-lucide="book-open"></i> API Docs
          </a>
          <a href="https://opensource.org/licenses/MIT" target="_blank" rel="noopener noreferrer">
            <i data-lucide="scale"></i> MIT License
          </a>
        </div>
        <p class="footer-copyright">© 2017-2025 • Open Source Software</p>
        <p class="footer-copyright" style="margin-top: 0.5rem; font-size: 0.85rem; opacity: 0.7;">Icons from <a
            href="https://lucide.dev" target="_blank" rel="noopener noreferrer"
            style="color: inherit; text-decoration: underline;">Lucide</a> (ISC License)</p>
      </div>
    </div>
  </footer>

  <!-- Inline SVG Icons - From Lucide (https://lucide.dev) - ISC License -->
  <svg style="display: none;" xmlns="http://www.w3.org/2000/svg">
    <symbol id="icon-shield-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
      <path d="m9 12 2 2 4-4" />
    </symbol>
    <symbol id="icon-lightbulb" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5" />
      <path d="M9 18h6" />
      <path d="M10 22h4" />
    </symbol>
    <symbol id="icon-link" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
      stroke-linejoin="round">
      <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
      <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
    </symbol>
    <symbol id="icon-globe" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <circle cx="12" cy="12" r="10" />
      <path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" />
      <path d="M2 12h20" />
    </symbol>
    <symbol id="icon-puzzle" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path
        d="M19.439 7.85c-.049.322.059.648.289.878l1.568 1.568c.47.47.706 1.087.706 1.704s-.235 1.233-.706 1.704l-1.611 1.611a.98.98 0 0 1-.837.276c-.47-.07-.802-.48-.968-.925a2.501 2.501 0 1 0-3.214 3.214c.446.166.855.497.925.968a.979.979 0 0 1-.276.837l-1.61 1.61a2.404 2.404 0 0 1-1.705.707 2.402 2.402 0 0 1-1.704-.706l-1.568-1.568a1.026 1.026 0 0 0-.877-.29c-.493.074-.84.504-1.02.968a2.5 2.5 0 1 1-3.237-3.237c.464-.18.894-.527.967-1.02a1.026 1.026 0 0 0-.289-.877l-1.568-1.568A2.402 2.402 0 0 1 1.998 12c0-.617.236-1.234.706-1.704L4.23 8.77c.24-.24.581-.353.917-.303.515.077.877.528 1.073 1.01a2.5 2.5 0 1 0 3.259-3.259c-.482-.196-.933-.558-1.01-1.073-.05-.336.062-.676.303-.917l1.525-1.525A2.402 2.402 0 0 1 12 1.998c.617 0 1.234.236 1.704.706l1.568 1.568c.23.23.556.338.877.29.493-.074.84-.504 1.02-.968a2.5 2.5 0 1 1 3.237 3.237c-.464.18-.894.527-.967 1.02Z" />
    </symbol>
    <symbol id="icon-github" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path
        d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" />
      <path d="M9 18c-4.51 2-5-2-7-2" />
    </symbol>
    <symbol id="icon-package" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path d="m7.5 4.27 9 5.15" />
      <path
        d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" />
      <path d="m3.3 7 8.7 5 8.7-5" />
      <path d="M12 22V12" />
    </symbol>
    <symbol id="icon-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
      stroke-linejoin="round">
      <rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
      <path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
    </symbol>
    <symbol id="icon-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path d="M20 6 9 17l-5-5" />
    </symbol>
    <symbol id="icon-arrow-up" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path d="m5 12 7-7 7 7" />
      <path d="M12 19V5" />
    </symbol>
    <symbol id="icon-external-link" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path d="M15 3h6v6" />
      <path d="M10 14 21 3" />
      <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
    </symbol>
    <symbol id="icon-zap" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
      stroke-linejoin="round">
      <path
        d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z" />
    </symbol>
    <symbol id="icon-settings" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path
        d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" />
      <circle cx="12" cy="12" r="3" />
    </symbol>
    <symbol id="icon-upload" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
      <polyline points="17 8 12 3 7 8" />
      <line x1="12" x2="12" y1="3" y2="15" />
    </symbol>
    <symbol id="icon-send" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
      stroke-linejoin="round">
      <path d="m22 2-7 20-4-9-9-4Z" />
      <path d="M22 2 11 13" />
    </symbol>
    <symbol id="icon-alert-circle" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <circle cx="12" cy="12" r="10" />
      <line x1="12" x2="12" y1="8" y2="12" />
      <line x1="12" x2="12.01" y1="16" y2="16" />
    </symbol>
    <symbol id="icon-download" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
      <polyline points="7 10 12 15 17 10" />
      <line x1="12" x2="12" y1="15" y2="3" />
    </symbol>
    <symbol id="icon-sparkles" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path
        d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" />
      <path d="M5 3v4" />
      <path d="M19 17v4" />
      <path d="M3 5h4" />
      <path d="M17 19h4" />
    </symbol>
    <symbol id="icon-layers" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path
        d="m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z" />
      <path d="m22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65" />
      <path d="m22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65" />
    </symbol>
    <symbol id="icon-book-open" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />
      <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
    </symbol>
    <symbol id="icon-scale" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
      stroke-linecap="round" stroke-linejoin="round">
      <path d="m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z" />
      <path d="m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z" />
      <path d="M7 21h10" />
      <path d="M12 3v18" />
      <path d="M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2" />
    </symbol>
  </svg>

  <script>
    // Helper function to create icon elements
    function createIcon(name) {
      const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
      const use = document.createElementNS("http://www.w3.org/2000/svg", "use");
      use.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", `#icon-${name}`);
      svg.appendChild(use);
      svg.setAttribute("width", "20");
      svg.setAttribute("height", "20");
      svg.setAttribute("aria-hidden", "true");
      return svg;
    }

    document.addEventListener('DOMContentLoaded', () => {
      // Replace all icon placeholders with actual SVG icons
      document.querySelectorAll('[data-lucide]').forEach(el => {
        const iconName = el.getAttribute('data-lucide');
        const svg = createIcon(iconName);
        el.replaceWith(svg);
      });

      // Highlight code blocks
      Prism.highlightAll();

      const tags = document.querySelectorAll(".tag");
      const tagBoxes = document.querySelectorAll(".tag-box");
      const tagsWrapper = document.querySelector(".tags-boxes");
      let autoRotateInterval, restartTimeout, currentIndex = 0, hasInteracted = false;

      const showTag = (index) => {
        tags.forEach(t => t.classList.remove("active"));
        tagBoxes.forEach(box => box.classList.remove("active"));
        tags[index].classList.add("active");
        document.querySelector(`.tag-box.${tags[index].dataset.feature}`)?.classList.add("active");
      };

      const startAutoRotate = () => {
        clearInterval(autoRotateInterval);
        clearTimeout(restartTimeout);
        autoRotateInterval = setInterval(() => {
          currentIndex = (currentIndex + 1) % tags.length;
          showTag(currentIndex);
        }, 5000);
      };

      const stopAutoRotate = () => {
        clearInterval(autoRotateInterval);
        clearTimeout(restartTimeout);
      };

      tags.forEach((tag, index) => {
        tag.addEventListener("click", function () {
          stopAutoRotate();

          if (this.classList.contains("active") && hasInteracted) {
            tags.forEach(t => t.classList.remove("active"));
            tagBoxes.forEach(box => box.classList.remove("active"));
            tagsWrapper.style.minHeight = "0";
            hasInteracted = false;
          } else {
            if (!hasInteracted) {
              hasInteracted = true;
              tagsWrapper.style.minHeight = "120px";
            }
            currentIndex = index;
            showTag(index);
            restartTimeout = setTimeout(startAutoRotate, 5000);
          }
        });
      });

      document.querySelectorAll(".install-tab").forEach(tab => {
        tab.addEventListener("click", function () {
          document.querySelectorAll(".install-tab").forEach(t => t.classList.remove("active"));
          document.querySelectorAll(".install-panel").forEach(p => p.classList.remove("active"));
          this.classList.add("active");
          document.querySelector(`[data-panel="${this.dataset.tab}"]`).classList.add("active");
        });
      });

      document.querySelectorAll(".copy-btn").forEach(btn => {
        btn.addEventListener("click", function () {
          const code = (this.closest(".code-copy-reference") ?? this.previousElementSibling)
            .querySelector("code").textContent;
          navigator.clipboard?.writeText(code).then(() => {
            const icon = this.querySelector("svg");
            const use = icon.querySelector("use");
            use.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "#icon-check");
            setTimeout(() => {
              use.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "#icon-copy");
            }, 1000);
          });
        });
      });

      const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => entry.isIntersecting && entry.target.classList.add('fade-in'));
      }, { threshold: 0.1 });

      document.querySelectorAll('.step-card, .complete-example-section').forEach(el => observer.observe(el));

      const scrollToTopBtn = document.getElementById('scroll-to-top');

      window.addEventListener('scroll', () => {
        scrollToTopBtn.classList.toggle('visible', window.pageYOffset > 500);
      });

      scrollToTopBtn.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' }));
    });
  </script>
</body>

</html>
